package com.kun.video.ui.dialog.message;

import cn.hutool.core.util.StrUtil;
import com.kun.video.context.ContextService;
import com.kun.video.thread.ComThreadPool;
import com.kun.video.util.ComUtil;
import com.kun.video.util.ResourceManager;
import javafx.animation.FadeTransition;
import javafx.animation.Interpolator;
import javafx.animation.PauseTransition;
import javafx.animation.SequentialTransition;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.util.Duration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.ref.WeakReference;
import java.util.EnumMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * TODO
 *
 * @author gzc
 * @since 2025/3/15
 **/
public class PopupMessage {
    private static final Logger log = LoggerFactory.getLogger(PopupMessage.class);

    /**
     * 消息类型样式配置
     */
    private static final Map<MessageType, StyleConfig> STYLE_CONFIG = new EnumMap<>(MessageType.class);

    static {
        STYLE_CONFIG.put(MessageType.SUCCESS, new StyleConfig(
                "#67c23a", "#f0f9eb", "/svg/check.svg"));
        STYLE_CONFIG.put(MessageType.ERROR, new StyleConfig(
                "#f56c6c", "#fef0f0", "/svg/close.svg"));
        STYLE_CONFIG.put(MessageType.WARNING, new StyleConfig(
                "#e6a23c", "#fdf6ec", "/svg/warning.svg"));
        STYLE_CONFIG.put(MessageType.INFO, new StyleConfig(
                "#909399", "#f4f4f5", "/svg/info.svg"));
    }

    /**
     * 动画时长（毫秒）
     */
    private static final int ANIMATION_DURATION = 100;
    private String STYLE = """
            -fx-padding:9 20 9 20;
            -fx-background-radius: 8px;
            -fx-font-size: 13px;
            -fx-spacing: 5px;
            """;

    private final ComThreadPool comThreadPool;
    private final PopupConfig popupConfig;


    public PopupMessage() {
        this(PopupConfig.builder().build());
    }

    public PopupMessage(PopupConfig popupConfig) {
        this.comThreadPool = ContextService.getBean(ComThreadPool.class);
        this.popupConfig = popupConfig;
    }

    public void error(String message) {
        show(popupConfig.message(message));
    }

    public void error(String message, long timed) {
        StyleConfig styleConfig = STYLE_CONFIG.get(MessageType.ERROR);
        this.popupConfig.setMessage(message);
        this.popupConfig.setTimed(timed);
        this.popupConfig.setBackgroundColor(styleConfig.backgroundColor);
        this.popupConfig.setFontColor(styleConfig.fontColor);
        this.popupConfig.setSvgPath(styleConfig.iconPath);
//         this.popupConfig.message(message).timed(timed).backgroundColor(styleConfig.backgroundColor).svgPath(styleConfig.iconPath).fontColor(styleConfig.fontColor);
        show(popupConfig);
    }

    public void success(String message) {
        show(popupConfig.message(message));
    }

    public void success(String message, long timed) {
        StyleConfig styleConfig = STYLE_CONFIG.get(MessageType.SUCCESS);
        this.popupConfig.message(message).timed(timed).backgroundColor(styleConfig.backgroundColor).svgPath(styleConfig.iconPath);
        show(popupConfig);
    }

    public void show(PopupConfig popupConfig) {
        comThreadPool.runAsync(() -> {
            if (StrUtil.isNotBlank(popupConfig.getBackgroundColor())) {
                STYLE += StrUtil.format(";-fx-background-color: {}", popupConfig.getBackgroundColor());
            }
            if (StrUtil.isNotBlank(popupConfig.getFontColor())) {
                STYLE += StrUtil.format(";-fx-text-fill: {}", popupConfig.getFontColor());
            }
            Region svgRegion = ResourceManager.loadSvgRegion(popupConfig.getSvgPath(), null);
            WeakReference<Region> weakReference = new WeakReference<>(svgRegion);
            Label label = new Label(popupConfig.getMessage());
            HBox hBox = new HBox(svgRegion, label);
            hBox.setStyle(STYLE);

            // 添加淡入动画
            FadeTransition fadeIn = createFadeTransition(hBox, 0.0, 1.0, ANIMATION_DURATION);
            fadeIn.play();
            ComUtil.uiThreadRun(() -> {
                Stage popup = createStage(hBox);
                popup.show();
                // 延时关闭提示框
                asyncClose(popup);
            });
        });
    }

    private Stage createStage(Parent parent) {
        Stage popup = new Stage();
        popup.initStyle(StageStyle.TRANSPARENT);
        popup.setAlwaysOnTop(true);
//            popup.initModality(Modality.APPLICATION_MODAL);
        // 改为非模态窗口避免阻塞
        popup.initModality(Modality.NONE);
        popup.centerOnScreen();
        Scene scene = new Scene(parent);
        // 背景透明
        scene.setFill(Color.TRANSPARENT);
        popup.setScene(scene);
        return popup;
    }

    /**
     * 异步关闭弹出框
     */
    private void asyncClose(Stage stage) {
        comThreadPool.runAsync(() -> {
            try {
                TimeUnit.MILLISECONDS.sleep(popupConfig.getTimed());
                if (stage.isShowing()) {
                    // 创建动画序列：淡出 -> 关闭
                    FadeTransition fadeOut = createFadeTransition((HBox) stage.getScene().getRoot(), 1.0, 0.0, ANIMATION_DURATION);
                    PauseTransition cleanup = new PauseTransition(Duration.millis(ANIMATION_DURATION));
                    cleanup.setOnFinished(e -> ComUtil.uiThreadRun(stage::close));
                    new SequentialTransition(fadeOut, cleanup).play();
                }
            } catch (Exception e) {
                Thread.currentThread().interrupt();
                log.warn("弹窗关闭任务被中断");
            }
        });
    }

    /**
     * 创建透明度动画
     */
    private FadeTransition createFadeTransition(HBox node, double from, double to, int duration) {
        FadeTransition ft = new FadeTransition(Duration.millis(duration), node);
        ft.setFromValue(from);
        ft.setToValue(to);
        ft.setInterpolator(Interpolator.EASE_BOTH);
        return ft;
    }


    /**
     * 消息类型枚举
     */
    public enum MessageType {
        SUCCESS, ERROR, WARNING, INFO
    }

    /**
     * 样式配置记录类
     */
    private record StyleConfig(
            String fontColor,
            String backgroundColor,
            String iconPath
    ) {
    }

}
